﻿using System;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;

namespace WindsorInitConfig {
    /// <summary>
    /// http://stackoverflow.com/questions/4398101/castle-windsor-strange-behaviour-wth-property-injection-and-factory-method
    /// </summary>
    public class ExceptionInConstructor {
        public class MyDependency : IMyDependency {
            public MyDependency(bool error) {
                if (error) throw new Exception("I error on creation");
            }
        }

        public interface IMyDependency {}

        public class MyConsumer {
            public IMyDependency MyDependency { get; set; }
        }

        [TestFixture]
        public class ProgramTest {
            [Test]
            public void CreateWithoutError() //Works as expected
            {
                var container = new WindsorContainer().Register(
                    Component.For<IMyDependency>().UsingFactoryMethod(() => new MyDependency(false)).LifeStyle.Transient,
                    Component.For<MyConsumer>().LifeStyle.Transient
                    );

                var consumer = container.Resolve<MyConsumer>();

                Assert.IsNotNull(consumer);
                Assert.IsNotNull(consumer.MyDependency);
            }

            [Test]
            public void CreateWithError_WhatShouldHappen() //I would expect an error since it can't create MyDependency
            {
                var container = new WindsorContainer().Register(
                    Component.For<IMyDependency>().UsingFactoryMethod(() => new MyDependency(true)).LifeStyle.Transient,
                    Component.For<MyConsumer>().LifeStyle.Transient
                    );
                Assert.Throws<Exception>(() => container.Resolve<MyConsumer>());
            }

            [Test]
            public void CreateWithError_WhatActuallyHappens() //Gives me back a consumer, but ignores MyDependency
            {
                var container = new WindsorContainer().Register(
                    Component.For<IMyDependency>().UsingFactoryMethod(() => new MyDependency(true)).LifeStyle.Transient,
                    Component.For<MyConsumer>().LifeStyle.Transient
                    );

                var consumer = container.Resolve<MyConsumer>();

                Assert.IsNotNull(consumer);
                Assert.IsNotNull(consumer.MyDependency); //Basically fails silently!
            }
        }
    }
}